package nash.controller;

import com.sun.jersey.api.view.Viewable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import nash.data.StaticDataController;
import nash.model.NashChange;
import nash.model.Person;
import nash.model.SituationChange;
import nash.viewable.NashViewable;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Path("/")
public class NashController {

    @POST
    public Viewable getPostViewable() {
        return getViewable();
    }

    @GET
    public Viewable getViewable() {
        NashViewable nw = new NashViewable();
        nw.setNashMessages(StaticDataController.getAllNashMessages());
        nw.setSituationMessages(StaticDataController.getAllSituationMessages());
        List<Person> allPeople = StaticDataController.getAllPeople();
        nw.setNamesMap(new HashMap<Long,String>());
        for ( Person p : allPeople ) {
            if ( "nash".equals(p.getType()) ) {
                nw.setNash(p.getName());
            }
            if ( "situation".equals(p.getType()) ) {
                nw.setSituation(p.getName());
            }
            nw.getNamesMap().put(p.getId(), p.getName());
        }
        return new Viewable("/viewable/index", nw);
    }

    @POST
    @Path("formSubmit/changeNash")
    public Viewable submitChangeNash(@FormParam("password") String password, @FormParam("to") String to, @FormParam("description") String message) throws URISyntaxException {
        JSONObject jo = new JSONObject();
        jo.put("password", password);
        jo.put("to", to);
        jo.put("description", message);
        newNash(jo.toString());
        return new Viewable("/viewable/redirect","");
    }

    @POST
    @Path("formSubmit/changeSituation")
    public Viewable submitSituationChange(@FormParam("password") String password, @FormParam("to") String to, @FormParam("description") String message) throws URISyntaxException {
        JSONObject jo = new JSONObject();
        jo.put("password", password);
        jo.put("to", to);
        jo.put("description", message);
        newSituation(jo.toString());
        return new Viewable("/viewable/redirect","");
    }

    @POST
    @Path("formSubmit/addPerson")
    public Viewable submitNewPerson(@FormParam("password") String password, @FormParam("name") String name,
            @FormParam("emailAddress") String email ) throws URISyntaxException {
        JSONObject jo = new JSONObject();
        jo.put("password", password);
        jo.put("name", name);
        jo.put("emailAddress", email);
        createPerson(jo.toString());
        return new Viewable("/viewable/redirect","");
    }

    @GET
    @Path("changeNash")
    public Viewable newNash() {
        return new Viewable("/viewable/newNash", StaticDataController.getAllPeople());
    }

    @GET
    @Path("changeSituation")
    public Viewable newSituation() {
        return new Viewable("/viewable/newSituation", StaticDataController.getAllPeople());
    }

    @GET
    @Path("addPerson")
    public Viewable addPerson() {
        return new Viewable("/viewable/addPerson", "");
    }

    @GET
    @Path("message")
    @Produces("application/json")
    public String getAllMessages() {
        JSONObject messages = new JSONObject();
        JSONArray ja = JSONArray.fromObject(StaticDataController.getAllNashMessages());
        JSONArray ja2 = JSONArray.fromObject(StaticDataController.getAllSituationMessages());
        messages.put("nashMessages", ja);
        messages.put("situationMessages", ja2);
        return messages.toString();
    }

    @POST
    @Path("newNash")
    public Response newNash(String newNash) {
        JSONObject nashJson = JSONObject.fromObject(newNash);
        String pw = nashJson.getString("password");
        if (!pw.equals("botch58")) {
            return Response.status(Status.FORBIDDEN).build();
        }
        String message = "";
        String subject = "";
        String newNashName = nashJson.getString("to");
        Long newNashId = Long.parseLong(newNashName);
        List<Person> people = StaticDataController.getAllPeople();
        String description = nashJson.getString("description");
        Date d = (Calendar.getInstance().getTime());
        NashChange m = new NashChange();
        Person oldNash = null;
        for (Person p : people) {
            if ("nash".equals(p.getType())) {
                oldNash = p;
            }
        }
        for (Person p : people) {
            if (p.getId().equals(newNashId)) {
                subject = "New Nash: " + p.getName();
                if (oldNash == null) {
                    m.setPersonTo(newNashId);
                    m.setPersonFrom(null);
                    message += "Nash now belongs to " + p.getName() + "\n\n";
                } else {
                    m.setPersonTo(newNashId);
                    m.setPersonFrom(oldNash.getId());
                    if ("situation".equals(p.getType())) {
                        SituationChange s = new SituationChange();
                        s.setPersonFrom(newNashId);
                        s.setPersonTo(oldNash.getId());
                        s.setText("Auto-change due to THE SITUATION stealing NASH");
                        s.setTimestamp(d);
                        StaticDataController.createMessage(s);
                        oldNash.setType("situation");
                        message += oldNash.getName() + " is now THE SITUATION because he was Nash \n\n";
                    } else {
                        oldNash.setType("none");
                    }
                    StaticDataController.updatePerson(oldNash);
                }
                p.setType("nash");
                StaticDataController.updatePerson(p);
            }
        }
        m.setText(description);
        m.setTimestamp(d);
        message += "Reason: " + description + "\n";
        StaticDataController.createMessage(m);
        sendEmail(subject, message);
        return Response.ok().build();
    }

    @POST
    @Path("newSituation")
    public Response newSituation(String newSituation) {
        JSONObject situationJson = JSONObject.fromObject(newSituation);
        String pw = situationJson.getString("password");
        if (!pw.equals("botch58")) {
            return Response.status(Status.FORBIDDEN).build();
        }
        String message = "";
        String subject = "";
        String newSituationName = situationJson.getString("to");
        Long newSituationId = Long.parseLong(newSituationName);
        List<Person> people = StaticDataController.getAllPeople();
        String description = situationJson.getString("description");
        Person oldSituation = null;
        SituationChange m = new SituationChange();
        for (Person p : people) {
            if ("situation".equals(p.getType())) {
                oldSituation = p;
            }
        }
        for (Person p : people) {
            if (p.getId().equals(newSituationId)) {
                p.setType("situation");
                subject = "New Situation: " + p.getName();
                message += "THE SITUATION now belongs to " + p.getName();
                m.setPersonTo(p.getId());
                if (oldSituation != null) {
                    oldSituation.setType("none");
                    StaticDataController.updatePerson(oldSituation);
                    m.setPersonFrom(oldSituation.getId());
                } else {
                    m.setPersonFrom(null);
                }
                StaticDataController.updatePerson(p);
            }
        }
        m.setText(description);
        m.setTimestamp(Calendar.getInstance().getTime());
        message += "\n\nReason: " + description;
        StaticDataController.createMessage(m);
        sendEmail(subject, message);
        return Response.ok().build();
    }

    @GET
    @Path("person")
    @Produces("application/json")
    public String getAllPeople() {
        JSONArray ja = JSONArray.fromObject(StaticDataController.getAllPeople());
        return ja.toString();
    }

    @POST
    @Path("person")
    public Response createPerson(String person) throws URISyntaxException {
        JSONObject jo = JSONObject.fromObject(person);

        String pw = jo.getString("password");
        if (!pw.equals("botch58")) {
            return Response.status(Status.FORBIDDEN).build();
        }
        Person p = (Person) JSONObject.toBean(jo, Person.class);
        StaticDataController.createPerson(p);
        return Response.created(new URI("")).build();
    }

    private void sendEmail(String subject, String message) {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        props.put("mail.smtp.host", "smtp.comcast.net");

        try {
            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("nash@sugarvale.com"));
            List<Person> allPeople = StaticDataController.getAllPeople();
            for (Person p : allPeople) {
                msg.addRecipient(Message.RecipientType.TO,
                        new InternetAddress(p.getEmailAddress()));
            }
            msg.setSubject(subject);
            msg.setText(message);
            Transport.send(msg);
        } catch (AddressException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}
